/**
 * File转Base64
 * @param file  File对象
 * @returns {Promise<unknown>}
 * @cenken
 */
export async function FileToBase64(file: File) {
    return new Promise((resolve, reject) => {
        const fileReader = new FileReader()
        fileReader.readAsDataURL(file)
        fileReader.onload = res => {
            const result = res.target.result
            result ? resolve(result) : reject(null)
        }
    })
}

/**
 * base64转File类型,Blob转File
 * @param base64 base64
 * @returns {File|null}
 * @cenken
 */
export const Base64ToFile = (base64) =>{
    let name = Math.random().toString(36).slice(2) + '.'
    if (base64 instanceof Blob){ // Blob类型
        const map = FileMap(base64.type,true)
        return new File([base64],name + map.name,{type:base64.type})
    }
    let {map,blob} = Base64ToBlob(base64)
    if (null === blob){
        return null
    }
    return new File([blob], name + map.name, {type: map.data})
}

/**
 * base64转Blob类型
 * @param base64    base64
 * @returns {{blob, map: {data: string, name: string}}|null}
 * @cenken
 */
export const Base64ToBlob = (base64) =>{
    if ('' === base64 || null === base64 || 'null' === base64 || undefined === base64 || 'undefined' === base64 || ' ' === base64){
        return null
    }
    base64 = base64.split(',')
    let base = base64.length > 1 ? base64[1] : base64[0] // 有data前缀和无前缀判断
    let map = FileMap(base)
    const byteString = window.atob(base)
    const arrayBuffer = new ArrayBuffer(byteString.length)
    const uint8Array = new Uint8Array(arrayBuffer)
    for (let i = 0 ; i < byteString.length ; i ++){
        uint8Array[i] = byteString.charCodeAt(i)
    }
    const blob = new Blob([arrayBuffer],{type: map.data})
    return {map, blob}
}


/**
 * 类型匹配
 * @param data  base64或Blob的type
 * @param flag  如传入Blob.type则需传true，base64该字段无需填写
 * @returns {{data: string, name: string}}
 * @cenken
 */
const FileMap = (data,flag) =>{
    let map
    let count = 3 // 计数
    while (true){
        if (flag){
            map = fileExtensionMap.find(_=>{
                return _.data === data
            })
        }else {
            map = fileExtensionMap.find(_=>{
                return _.type === data.substring(0,count)
            })
        }
        if (undefined === map || 'undefined' === map || null === map){
            if (count < 6){
                count += 1
            }else {
                break
            }
        }else {
            break
        }
    }
    if (undefined === map || 'undefined' === map){
        map = {name:'jpeg',data:'image/jpeg'}
    }
    return map
}

/**
 * 文件类型映射
 * @type {[{data: string, name: string, type: string}, {data: string, name: string, type: string}, {data: string, name: string, type: string}, {data: string, name: string, type: string}, {data: string, name: string, type: string}, null, null, null, null, null, null, null, null, null, null, null, null, null, null]}
 */
const fileExtensionMap = [
    {type: '/9j', name: 'jpeg', data: 'image/jpeg'},
    {type: '/9J', name: 'jpeg', data: 'image/jpeg'},
    {type: 'iVB', name: 'png', data: 'image/png'},
    {type: 'R0l', name: 'gif', data: 'image/gif'},
    {type: 'Qk0', name: 'bmp', data: 'image/bmp'},
    {type: 'Ukl', name: 'webp', data: 'image/webp'},
    {type: 'SUk', name: 'tiff', data: 'image/tiff'},
    {type:'AAAB',name:'ico',data: 'image/x-icon'},
    {type: 'PHN2',name: 'svg',data: 'image/svg+xml'},
    {type: 'SUQ', name: 'mpeg', data: 'audio/mpeg'},
    {type: 'Rk1', name: 'wav', data: 'audio/wav'},
    {type: 'b2dv', name: 'ogg', data: 'audio/ogg'},
    {type: 'AAKS', name: 'mp4', data: 'video/mp4'},
    {type: 'AAAA', name: 'mp4', data: 'video/mp4'},
    {type: 'G1k0', name: 'webm', data: 'video/webm'},
    {type: 'Rmx2', name: 'flv', data: 'video/x-flv'},
    {type:'JVBER',name: 'pdf',data: 'application/pdf'},
    {type:'UEs',name:'docx',data: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'},
    {type: 'dGV',name: 'txt',data: 'text/plain'},
    {type: 'ZGVz',name: 'csv',data: 'text/csv'},
    {type: 'PHh',name: 'xml',data: 'text/xml'},
]